import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class AnnotationApplication {
    public static void main(String[] args) {
        // 1. 内置注解演示
        builtInAnnotationDemo();

        // 2. 自定义注解演示
        customAnnotationDemo();

        // 3. 注解处理器演示
        annotationProcessorDemo();

        // 4. 实际应用演示
        practicalApplicationDemo();
    }

    /**
     * 内置注解演示
     */
    private static void builtInAnnotationDemo() {
        System.out.println("=== 内置注解演示 ===");

        // @Override注解确保方法重写正确
        Animal animal = new Dog();
        animal.makeSound();  // 调用重写的方法

        // @Deprecated注解标记过时方法
        OldClass oldObj = new OldClass();
        oldObj.newMethod();      // 推荐使用
        oldObj.oldMethod();      // 过时方法，编译器会警告

        // @SuppressWarnings注解抑制警告，在最小范围使用，避免在整个类
        @SuppressWarnings("unchecked")
        List rawList = new ArrayList();  // 抑制未检查警告
        rawList.add("item");

        System.out.println("内置注解演示完成\n");
    }

    /**
     * 自定义注解演示
     */
    private static void customAnnotationDemo() {
        System.out.println("=== 自定义注解演示 ===");

        // 获取类上的注解
        Class<AnnotatedClass> clazz = AnnotatedClass.class;

        if (clazz.isAnnotationPresent(Entity.class)) {
            Entity entity = clazz.getAnnotation(Entity.class);
            System.out.println("实体表名: " + entity.tableName());
            System.out.println("实体描述: " + entity.description());
        }

        // 获取字段上的注解
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Column.class)) {
                Column column = field.getAnnotation(Column.class);
                System.out.println("字段 " + field.getName() +
                        " -> 列名: " + column.name() +
                        ", 可空: " + column.nullable());
            }

            if (field.isAnnotationPresent(Validate.class)) {
                Validate validate = field.getAnnotation(Validate.class);
                System.out.println("字段 " + field.getName() +
                        " -> 最小值: " + validate.min() +
                        ", 最大值: " + validate.max());
            }
        }

        // 获取方法上的注解
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Log.class)) {
                Log log = method.getAnnotation(Log.class);
                System.out.println("方法 " + method.getName() +
                        " -> 日志级别: " + log.level() +
                        ", 消息: " + log.message());
            }
        }

        System.out.println();
    }

    /**
     * 注解处理器演示
     */
    private static void annotationProcessorDemo() {
        System.out.println("=== 注解处理器演示 ===");

        try {
            // 创建测试对象
            AnnotatedClass obj = new AnnotatedClass();
            obj.setId(1L);
            obj.setName("测试用户");
            obj.setAge(25);

            // 使用验证处理器
            ValidationProcessor validator = new ValidationProcessor();
            boolean isValid = validator.validate(obj);
            System.out.println("验证结果: " + (isValid ? "通过" : "失败"));

            // 测试无效数据
            obj.setAge(200);  // 超出范围
            isValid = validator.validate(obj);
            System.out.println("无效数据验证结果: " + (isValid ? "通过" : "失败"));

            // 使用日志处理器
            LogProcessor logProcessor = new LogProcessor();
            logProcessor.processLogs(obj);

        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println();
    }

    /**
     * 实际应用演示
     */
    private static void practicalApplicationDemo() {
        System.out.println("=== 实际应用演示 ===");

        // 简单的ORM映射演示
        AnnotatedClass obj = new AnnotatedClass();
        obj.setId(1L);
        obj.setName("张三");
        obj.setAge(30);

        SimpleORM orm = new SimpleORM();
        String sql = orm.generateInsertSQL(obj);
        System.out.println("生成的SQL: " + sql);

        System.out.println();
    }
}

// ========== 自定义注解定义 ==========

/**
 * 实体注解 - 类级别
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface Entity {
    String tableName() default "";
    String description() default "";
}

/**
 * 列注解 - 字段级别
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    String name() default "";
    boolean nullable() default true;
    int length() default 255;
}

/**
 * 验证注解 - 字段级别
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Validate {
    int min() default 0;
    int max() default Integer.MAX_VALUE;
    String message() default "验证失败";
}

/**
 * 日志注解 - 方法级别
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Log {
    String level() default "INFO";
    String message() default "";
}

/**
 * 标记注解 - 无参数
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Deprecated2 {
}

// ========== 使用注解的类 ==========

@Entity(tableName = "users", description = "用户表")
class AnnotatedClass {
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "username", nullable = false, length = 50)
    private String name;

    @Column(name = "age")
    @Validate(min = 0, max = 150, message = "年龄必须在0-150之间")
    private Integer age;

    // 构造器
    public AnnotatedClass() {}

    // Getter和Setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }

    @Log(level = "DEBUG", message = "保存用户信息")
    public void save() {
        System.out.println("保存用户: " + this);
    }

    @Log(level = "INFO", message = "删除用户信息")
    @Deprecated2
    public void delete() {
        System.out.println("删除用户: " + this);
    }

    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', age=" + age + "}";
    }
}

// ========== 注解处理器 ==========

/**
 * 验证处理器
 */
class ValidationProcessor {
    public boolean validate(Object obj) {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            if (field.isAnnotationPresent(Validate.class)) {
                Validate validate = field.getAnnotation(Validate.class);
                field.setAccessible(true);

                try {
                    Object value = field.get(obj);
                    if (value instanceof Integer) {
                        int intValue = (Integer) value;
                        if (intValue < validate.min() || intValue > validate.max()) {
                            System.out.println("验证失败: " + field.getName() +
                                    " = " + intValue + ", " + validate.message());
                            return false;
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }

        return true;
    }
}

/**
 * 日志处理器
 */
class LogProcessor {
    public void processLogs(Object obj) {
        Class<?> clazz = obj.getClass();
        Method[] methods = clazz.getDeclaredMethods();

        for (Method method : methods) {
            if (method.isAnnotationPresent(Log.class)) {
                Log log = method.getAnnotation(Log.class);
                System.out.println("[" + log.level() + "] " +
                        method.getName() + "() - " + log.message());
            }
        }
    }
}

/**
 * 简单的ORM映射器
 */
class SimpleORM {
    public String generateInsertSQL(Object obj) {
        Class<?> clazz = obj.getClass();

        // 获取表名
        String tableName = "unknown_table";
        if (clazz.isAnnotationPresent(Entity.class)) {
            Entity entity = clazz.getAnnotation(Entity.class);
            tableName = entity.tableName();
        }

        // 构建SQL
        StringBuilder sql = new StringBuilder("INSERT INTO " + tableName + " (");
        StringBuilder values = new StringBuilder(" VALUES (");

        Field[] fields = clazz.getDeclaredFields();
        boolean first = true;

        for (Field field : fields) {
            if (field.isAnnotationPresent(Column.class)) {
                Column column = field.getAnnotation(Column.class);
                String columnName = column.name().isEmpty() ? field.getName() : column.name();

                if (!first) {
                    sql.append(", ");
                    values.append(", ");
                }

                sql.append(columnName);

                // 获取字段值
                field.setAccessible(true);
                try {
                    Object value = field.get(obj);
                    if (value instanceof String) {
                        values.append("'").append(value).append("'");
                    } else {
                        values.append(value);
                    }
                } catch (IllegalAccessException e) {
                    values.append("NULL");
                }

                first = false;
            }
        }

        sql.append(")");
        values.append(")");

        return sql.toString() + values.toString();
    }
}

// ========== 演示用的其他类 ==========

abstract class Animal {
    public abstract void makeSound();
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪！");
    }
}

class OldClass {
    @Deprecated
    public void oldMethod() {
        System.out.println("这是过时的方法");
    }

    public void newMethod() {
        System.out.println("这是新的推荐方法");
    }
}
